"""
Flask application exposing the registration algorithm over HTTP.
"""

from __future__ import annotations

import os
from typing import Any, Dict

from flask import Flask, jsonify, request

from config.settings import settings
from core.registration import registration_point_clouds

app = Flask(__name__)


def _validate_request(payload: Dict[str, Any]) -> Dict[str, Any]:
    scan_filename = payload.get("scan_file")
    bim_filename = payload.get("bim_file")

    if not scan_filename or not bim_filename:
        raise ValueError("Missing required parameters: scan_file and bim_file are required")

    if not os.path.exists(scan_filename):
        raise FileNotFoundError(f"Scan file not found: {scan_filename}")

    if not os.path.exists(bim_filename):
        raise FileNotFoundError(f"BIM file not found: {bim_filename}")

    return {
        "scan_filename": scan_filename,
        "bim_filename": bim_filename,
        "is_small_cloud": payload.get("is_small_cloud", settings.registration.is_small_cloud),
        "max_attempts": payload.get("max_attempts", settings.registration.max_attempts),
        "random_seed": payload.get("random_seed", settings.registration.random_seed),
    }


@app.route("/register", methods=["POST"])
def registration_icp():
    """
    点云配准API接口。

    请求体 JSON:
        - scan_file: 扫描点云文件路径
        - bim_file: BIM 模型文件路径
        - is_small_cloud (可选)
        - max_attempts (可选)
        - random_seed (可选)
    """
    try:
        data = request.get_json(force=True)  # type: ignore[arg-type]
        params = _validate_request(data)

        transformation_matrix = registration_point_clouds(
            scan_filename=params["scan_filename"],
            bim_filename=params["bim_filename"],
            is_small_cloud=params["is_small_cloud"],
            max_attempts=params["max_attempts"],
            random_seed=params["random_seed"],
        )

        return jsonify({"success": True, "transformation_matrix": transformation_matrix.tolist()})
    except FileNotFoundError as exc:
        return jsonify({"error": str(exc)}), 404
    except ValueError as exc:
        return jsonify({"error": str(exc)}), 400
    except Exception as exc:  # pragma: no cover - runtime safeguard
        return jsonify({"error": str(exc)}), 500


if __name__ == "__main__":  # pragma: no cover - script entry
    app.run(host="0.0.0.0", port=5000, debug=False)